package com.ydy.file.service.impl;

import com.ydy.common.constant.Constant;
import com.ydy.common.model.FileInfo;
import com.ydy.common.util.CodeUtil;
import com.ydy.common.util.PageHelperUtils;
import com.ydy.common.util.RedisUtil;
import com.ydy.common.vo.PageInfo;
import com.ydy.file.mapper.FileMapper;
import com.ydy.file.service.FileService;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class FileServiceImpl implements FileService {


    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private RedisTemplate<Serializable, Object> redisTemplate;

    @Override
    public void insertFileInfo(FileInfo fileInfo) {
        fileMapper.insertFileInfo(fileInfo);
    }

    @Override
    public List<FileInfo> queryFileInfo(FileInfo fileInfo, PageInfo pageInfo) {
        PageHelperUtils.startPage(pageInfo);
        return fileMapper.queryFileInfo(fileInfo,pageInfo);
    }

    @Override
    public void deleteFileInfo(FileInfo fileInfo) {
        String fileCode = fileInfo.getFileCode();
        fileMapper.deleteFileInfo(fileCode);
        RedisUtil redisUtil = new RedisUtil(redisTemplate);
        String serveUrl = String.valueOf(redisUtil.get(Constant.SERVE_URL));
        //删除文件
        File file = new File(fileInfo.getFileUrl().replace(serveUrl,""));
        if(file.exists() && file.isFile())file.delete();
    }

    @Override
    public FileInfo getFileInfo(MultipartFile file, String fileType) {
        //获取文件名称
        String fileName = file.getOriginalFilename();
        //获取文件名后缀
        String suffix = fileName.substring(file.getOriginalFilename().lastIndexOf("."));
        suffix = suffix.toLowerCase();
        FileInfo fileInfo = new FileInfo();

        Map<String,Object> filterMap = getFileFilterMap(fileType);
        String containsType = MapUtils.getString(filterMap,"containsType");
        String localPath = MapUtils.getString(filterMap,"localPath");
        String fileUrl = MapUtils.getString(filterMap,"fileUrl");

        if(containsType.contains(suffix)){
            String newFileName = CodeUtil.getCode() +suffix;
            File targetFile = new File(localPath, newFileName);
            if(!targetFile.getParentFile().exists()){    //注意，判断父级路径是否存在
                targetFile.getParentFile().mkdirs();
            }
            //保存
            try {
                FileUtils.copyInputStreamToFile(file.getInputStream(),targetFile);
                long size = file.getSize();
                fileInfo = new FileInfo(CodeUtil.getCode(),fileName, fileUrl+newFileName,fileType);
                fileMapper.insertFileInfo(fileInfo);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("上传失败！");
            }
        }else{
            throw new RuntimeException("文件格式有误，请上传"+containsType+"格式的文件");
        }
        return fileInfo;
    }

    private Map<String, Object> getFileFilterMap(String fileType) {

        Map<String,Object> map = new LinkedHashMap<>();

        String containsType = "";//包含的文件类型
        String localPath = "";//存储文件地址
        String fileUrl = "";//文件请求地址

        RedisUtil redisUtil = new RedisUtil(redisTemplate);
        String serveUrl = String.valueOf(redisUtil.get(Constant.SERVE_URL));

        switch (fileType){
            case Constant.FILE_IMAGE :
                containsType = Constant.IMAGE_TYPE;
                localPath = Constant.IMAGE_PATH;
                fileUrl = serveUrl + Constant.IMAGE_PATH;
                break;
            case Constant.FILE_PDF :
                containsType = Constant.PDF_TYPE;
                localPath = Constant.PDF_PATH;
                fileUrl = serveUrl + Constant.PDF_PATH;
                break;
            case Constant.FILE_WORD :
                containsType = Constant.WORD_TYPE;
                localPath = Constant.WORD_PATH;
                fileUrl = serveUrl + Constant.WORD_PATH;
                break;
            case Constant.FILE_EXCEL :
                containsType = Constant.EXCEL_TYPE;
                localPath = Constant.EXCEL_PATH;
                fileUrl = serveUrl + Constant.EXCEL_PATH;
                break;
            case Constant.FILE_VIDEO :
                containsType = Constant.VIDEO_TYPE;
                localPath = Constant.VIDEO_PATH;
                fileUrl = serveUrl + Constant.VIDEO_PATH;
                break;
        }

        map.put("containsType",containsType);
        map.put("localPath",localPath);
        map.put("fileUrl",fileUrl);
        return map;
    }
}
